

from CvPythonExtensions import *
import CvUtil
import CvMapGeneratorUtil
import random
import sys
from math import sqrt
from CvMapGeneratorUtil import FractalWorld
from CvMapGeneratorUtil import TerrainGenerator
from CvMapGeneratorUtil import FeatureGenerator

def getDescription():
	return "Generates a map with moon terrain"

def getNumCustomMapOptions():
	return 4
	
def getCustomMapOptionName(argsList):
    [iOption] = argsList
    option_names = {
        0:	"TXT_KEY_MAP_SCRIPT_MOUNTAIN_PATTERN",
        1:	"TXT_KEY_MAP_SCRIPT_MOUNTAIN_DENSITY",
        2:	"Dust Sea Setting",
        3:  "Terrain Attrition"
        }
    translated_text = unicode(CyTranslator().getText(option_names[iOption], ()))
    return translated_text

def getNumCustomMapOptionValues(argsList):
    [iOption] = argsList
    option_values = {
        0:	3,
        1:	3,
        2:	3,
        3:  2
        }
    return option_values[iOption]

def getCustomMapOptionDescAt(argsList):
    [iOption, iSelection] = argsList
    selection_names = {
        0:	{
            0: "TXT_KEY_MAP_SCRIPT_SCATTERED",
            1: "TXT_KEY_MAP_SCRIPT_RIDGELINES",
            2: "TXT_KEY_MAP_SCRIPT_CLUSTERED"
            },
        1:	{
            0: "TXT_KEY_MAP_SCRIPT_DENSE_PEAKS",
            1: "TXT_KEY_MAP_SCRIPT_NORMAL_PEAKS",
            2: "TXT_KEY_MAP_SCRIPT_THIN_PEAKS"
            },
        2:	{
            0: "Small",
            1: "Medium",
            2: "Large"
            },
        3:  {
            0: "On",
            1: "Off"
            }
        }
    translated_text = unicode(CyTranslator().getText(selection_names[iOption][iSelection], ()))
    return translated_text
	
def getCustomMapOptionDefault(argsList):
    [iOption] = argsList
    option_defaults = {
        0:	1,
        1:	1,
        2:	1,
        3:  0
        }
    return option_defaults[iOption]

def isAdvancedMap():
	"This map should show up in simple mode"
	return 0
	
def isClimateMap():
	return 0

def isSeaLevelMap():
	return 0

def beforeInit():
	# Roll a dice to determine if the cold region will be in north or south.
	gc = CyGlobalContext()
	dice = gc.getGame().getMapRand()
	global shiftMultiplier
	shiftRoll = dice.get(2, "North or South climate shift - Highlands PYTHON")
	if shiftRoll == 0: # Cold in north
		shiftMultiplier = 0.0
	else: # Cold in south
		shiftMultiplier = 1.0
	return 0

def getWrapX():
	return True
def getWrapY():
	return False

def getTopLatitude():
	global shiftMultiplier
	if shiftMultiplier == 0.0:
		return 85
	else:
		return 10
	
def getBottomLatitude():
	global shiftMultiplier
	if shiftMultiplier == 0.0:
		return -10
	else:
		return -85

def getGridSize(argsList):
	"Reduce grid sizes by one level."
	grid_sizes = {
		WorldSizeTypes.WORLDSIZE_DUEL:		(8,5),
		WorldSizeTypes.WORLDSIZE_TINY:		(10,6),
		WorldSizeTypes.WORLDSIZE_SMALL:		(13,8),
		WorldSizeTypes.WORLDSIZE_STANDARD:	(16,10),
		WorldSizeTypes.WORLDSIZE_LARGE:		(21,13),
		WorldSizeTypes.WORLDSIZE_HUGE:		(26,16)
	}

	if (argsList[0] == -1): # (-1,) is passed to function on loads
		return []
	[eWorldSize] = argsList
	return grid_sizes[eWorldSize]

def minStartingDistanceModifier():
	return -35

def generatePlotTypes():
	NiTextOut("Setting Plot Types (Python Highlands) ...")
	gc = CyGlobalContext()
	map = CyMap()
	dice = gc.getGame().getMapRand()
	iFlags = 0  # Disallow FRAC_POLAR flag, to prevent "zero row" problems.
	iW = map.getGridWidth()
	iH = map.getGridHeight()
	plotTypes = [PlotTypes.PLOT_LAND] * (iW*iH)
	terrainFrac = CyFractal()
	lakesFrac = CyFractal()
	
	# Get custom map user inputs.
	userInputGrain = map.getCustomMapOption(0)
	userInputPeaks = map.getCustomMapOption(1)
	userInputLakes = map.getCustomMapOption(2)

	# Varying grains for hills/peaks per map size and Mountain Ranges setting.
	# [clustered_grain, ridgelines_grain, scattered_grain]
	worldsizes = {
		WorldSizeTypes.WORLDSIZE_DUEL:      [3,4,5],
		WorldSizeTypes.WORLDSIZE_TINY:      [3,4,5],
		WorldSizeTypes.WORLDSIZE_SMALL:     [4,5,6],
		WorldSizeTypes.WORLDSIZE_STANDARD:  [4,5,6],
		WorldSizeTypes.WORLDSIZE_LARGE:     [4,5,6],
		WorldSizeTypes.WORLDSIZE_HUGE:      [4,5,6]
		}
	grain_list = worldsizes[map.getWorldSize()]
	grain_list.reverse()
	grain = grain_list[userInputGrain]
	
	# Peak density
	peak_list = [80, 87, 95]
	hill_list = [40, 45, 50]
	peaks = peak_list[userInputPeaks]
	hills = hill_list[userInputPeaks]
	
	# Lake density
	lake_list = [5, 10, 15]
	lake_grains = [4, 3, 2]
	lakes = lake_list[userInputLakes]
	lake_grain = lake_grains[userInputLakes]

	terrainFrac.fracInit(iW, iH, grain, dice, 0, -1, -1)
	lakesFrac.fracInit(iW, iH, lake_grain, dice, 0, -1, -1)

	iLakesThreshold = lakesFrac.getHeightFromPercent(lakes)
	iHillsThreshold = terrainFrac.getHeightFromPercent(hills)
	iPeaksThreshold = terrainFrac.getHeightFromPercent(peaks)

	# Now the main loop, which will assign the plot types.
	for x in range(iW):
		for y in range(iH):
			i = y*iW + x
			lakeVal = lakesFrac.getHeight(x,y)
			val = terrainFrac.getHeight(x,y)
			if lakeVal <= iLakesThreshold:
				plotTypes[i] = PlotTypes.PLOT_OCEAN
			elif val >= iPeaksThreshold:
				plotTypes[i] = PlotTypes.PLOT_PEAK
			elif val >= iHillsThreshold and val < iPeaksThreshold:
				plotTypes[i] = PlotTypes.PLOT_LAND
			else:
				plotTypes[i] = PlotTypes.PLOT_LAND

	return plotTypes


class MoonTerrainGenerator(CvMapGeneratorUtil.TerrainGenerator):
	def __init__(self, fracXExp=-1, fracYExp=-1, grain_amount=4,
                     iMariaBasaltPercent=40,iDustPlainsPercent=60,iCraterRimPercent=60,
                     iBareRockPercent=80,iCrateredPercent=60,
                     iPolarBottomLatitude=0.8,iPolarTopLatitude=0.2,iPolarPercent=30):

                self.gc = CyGlobalContext()
		self.map = CyMap()

		self.grain_amount = 4 + self.gc.getWorldInfo(self.map.getWorldSize()).getTerrainGrainChange()
		
		self.gc = CyGlobalContext()
		self.map = CyMap()

		self.iWidth = self.map.getGridWidth()
		self.iHeight = self.map.getGridHeight()

		self.mapRand = self.gc.getGame().getMapRand()
		self.iFlags = 0

		self.MariaBasalt=CyFractal()
		self.DustPlains=CyFractal()
		self.Cratered=CyFractal()
		self.BareRock=CyFractal()
		self.CraterRim=CyFractal()
		self.Polar=CyFractal()
		self.variation=CyFractal()

                self.iMariaBasaltTopPercent = 100
		self.iMariaBasaltBottomPercent = max(0,int(100-iMariaBasaltPercent))
		self.iDustPlainsTopPercent = 100
		self.iDustPlainsBottomPercent = max(0,int(100-iDustPlainsPercent))
		self.iCrateredTopPercent = 100
		self.iCrateredBottomPercent = max(0,int(100-iCrateredPercent))
		self.iBareRockTopPercent = 100
		self.iBareRockBottomPercent = max(0,int(100-iBareRockPercent))
		self.iPolarTopPercent = 100
		self.iPolarBottomPercent = max(0,int(100-iPolarPercent))
		self.iCraterRimTopPercent = 100
		self.iCraterRimBottomPercent = max(0,int(100-iCraterRimPercent))

		self.iMariaBasaltPercent = iMariaBasaltPercent
		self.iDustPlainsPercent = iDustPlainsPercent
		self.iCrateredPercent = iCrateredPercent
		self.iBareRockPercent = iBareRockPercent
		self.iCraterRimPercent = iCraterRimPercent
		self.iPolarPercent = iPolarPercent

		self.PolarBottomLatitude = iPolarBottomLatitude
		self.PolarTopLatitude = iPolarTopLatitude

                self.fracXExp = fracXExp
		self.fracYExp = fracYExp

		self.initFractals()
		
	def initFractals(self):
                self.MariaBasalt.fracInit(self.iWidth, self.iHeight, self.grain_amount+1, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iMariaBasaltTop = self.MariaBasalt.getHeightFromPercent(self.iMariaBasaltTopPercent)
		self.iMariaBasaltBottom = self.MariaBasalt.getHeightFromPercent(self.iMariaBasaltBottomPercent)

                self.DustPlains.fracInit(self.iWidth, self.iHeight, self.grain_amount+1, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iDustPlainsTop = self.DustPlains.getHeightFromPercent(self.iDustPlainsTopPercent)
		self.iDustPlainsBottom = self.DustPlains.getHeightFromPercent(self.iDustPlainsBottomPercent)

                self.Cratered.fracInit(self.iWidth, self.iHeight, self.grain_amount+1, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iCrateredTop = self.Cratered.getHeightFromPercent(self.iCrateredTopPercent)
		self.iCrateredBottom = self.Cratered.getHeightFromPercent(self.iCrateredBottomPercent)
		
                self.BareRock.fracInit(self.iWidth, self.iHeight, self.grain_amount+1, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iBareRockTop = self.BareRock.getHeightFromPercent(self.iBareRockTopPercent)
		self.iBareRockBottom = self.BareRock.getHeightFromPercent(self.iBareRockBottomPercent)

                self.Polar.fracInit(self.iWidth, self.iHeight, self.grain_amount+1, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iPolarTop = self.Polar.getHeightFromPercent(self.iPolarTopPercent)
		self.iPolarBottom = self.Polar.getHeightFromPercent(self.iPolarBottomPercent)

                self.CraterRim.fracInit(self.iWidth, self.iHeight, self.grain_amount+1, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iCraterRimTop = self.CraterRim.getHeightFromPercent(self.iCraterRimTopPercent)
		self.iCraterRimBottom = self.CraterRim.getHeightFromPercent(self.iCraterRimBottomPercent)

		self.variation.fracInit(self.iWidth, self.iHeight, self.grain_amount, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)

		self.terrainMariaBasalt = self.gc.getInfoTypeForString("TERRAIN_MARIABASALT")
		self.terrainDustPlains = self.gc.getInfoTypeForString("TERRAIN_DUSTPLAINS")
		self.terrainCratered = self.gc.getInfoTypeForString("TERRAIN_CRATERED")
		self.terrainCraterRim = self.gc.getInfoTypeForString("TERRAIN_CRATERRIM")
		self.terrainBareRock = self.gc.getInfoTypeForString("TERRAIN_BAREROCK")
		self.terrainDustSea = self.gc.getInfoTypeForString("TERRAIN_DUSTSEA")
		self.terrainPolar = self.gc.getInfoTypeForString("TERRAIN_POLAR")


	def getLatitudeAtPlot(self, iX, iY):
		lat = iY/float(self.iHeight) # 0.0 = south edge, 1.0 = north edge

		# Adjust latitude using self.variation fractal, to mix things up:
		lat += (128 - self.variation.getHeight(iX, iY))/(255.0 * 5.0)

		# Limit to the range [0, 1]:
		if lat < 0:
			lat = 0.0
		if lat > 1:
			lat = 1.0

		return lat

	def generateTerrain(self):		
		terrainData = [0]*(self.iWidth*self.iHeight)
		for x in range(self.iWidth):
			for y in range(self.iHeight):
				iI = y*self.iWidth + x
				terrain = self.generateTerrainAtPlot(x, y)
				terrainData[iI] = terrain

		return terrainData

	def generateTerrainAtPlot(self,iX,iY):


		lat = self.getLatitudeAtPlot(iX,iY)

		if (self.map.plot(iX, iY).isWater()):
			return self.map.plot(iX, iY).getTerrainType()

		terrainVal = self.MariaBasalt

                if ((lat > self.PolarBottomLatitude) or (lat < self.PolarTopLatitude)):
                    polarVal = self.Polar.getHeight(iX, iY)
                    if polarVal >= self.iPolarBottom:
                        terrainVal = self.terrainPolar
                    else:
                        mariabasaltVal = self.MariaBasalt.getHeight(iX, iY)
                        crateredVal = self.Cratered.getHeight(iX, iY)
                        dustplainsVal = self.DustPlains.getHeight(iX, iY)
                        barerockVal = self.BareRock.getHeight(iX, iY)
		
                        if ((crateredVal >= self.iCrateredBottom) and (crateredVal <= self.iCrateredTop)):
                            terrainVal = self.terrainCratered
                        elif ((dustplainsVal >= self.iDustPlainsBottom) and (dustplainsVal <= self.iDustPlainsTop)):
                            terrainVal = self.terrainDustPlains
                        elif ((barerockVal >= self.iBareRockBottom) and (barerockVal <= self.iBareRockTop)):
                            terrainVal = self.terrainBareRock
                else:
                    mariabasaltVal = self.MariaBasalt.getHeight(iX, iY)
                    crateredVal = self.Cratered.getHeight(iX, iY)
                    dustplainsVal = self.DustPlains.getHeight(iX, iY)
                    barerockVal = self.BareRock.getHeight(iX, iY)
		
                    if ((mariabasaltVal >= self.iMariaBasaltBottom) and (mariabasaltVal <= self.iMariaBasaltTop)):
			terrainVal = self.terrainMariaBasalt
                    elif ((crateredVal >= self.iCrateredBottom) and (crateredVal <= self.iCrateredTop)):
			terrainVal = self.terrainCratered
                    elif ((dustplainsVal >= self.iDustPlainsBottom) and (dustplainsVal <= self.iDustPlainsTop)):
			terrainVal = self.terrainDustPlains
                    elif ((barerockVal >= self.iBareRockBottom) and (barerockVal <= self.iBareRockTop)):
                        terrainVal = self.terrainBareRock
		
			

		if (terrainVal == TerrainTypes.NO_TERRAIN):
			return self.map.plot(iX, iY).getTerrainType()

		return terrainVal

def generateTerrainTypes():
	NiTextOut("Generating Terrain (Python Oasis) ...")
	terraingen = MoonTerrainGenerator()
	terrainTypes = terraingen.generateTerrain()
	return terrainTypes
       

def addRivers():
#make sure no rivers are added
	gc = CyGlobalContext()
	

def addLakes():
    #add crater rims
        gc = CyGlobalContext()
        dice = gc.getGame().getMapRand()
        map = gc.getMap()
        iW = map.getGridWidth()
        iH = map.getGridHeight()
        MapArea = iW * iH
        NumOfCraters = MapArea/100 + MapArea * dice.get(1000, "number of craters") / 30000
        CraterRim = gc.getInfoTypeForString("TERRAIN_CRATERRIM")
        for x in range (NumOfCraters):
            Rollx = dice.get((iW - 2), "Location of crater") + 1
            Rolly = dice.get((iH - 4), "Location of crater") + 2

            m11Plot = CyMap().plot((Rollx - 1),(Rolly - 1))
            m12Plot = CyMap().plot((Rollx - 1),Rolly)
            m21Plot = CyMap().plot(Rollx,(Rolly - 1))
            m22Plot = CyMap().plot(Rollx,Rolly)
            
            m01tPlot = CyMap().plot((Rollx - 2),(Rolly - 1)).getTerrainType()
            m02tPlot = CyMap().plot((Rollx - 2),Rolly).getTerrainType()
            m31tPlot = CyMap().plot((Rollx + 1),(Rolly - 1)).getTerrainType()
            m32tPlot = CyMap().plot((Rollx + 1),Rolly).getTerrainType()
            m10tPlot = CyMap().plot((Rollx - 1),(Rolly - 2)).getTerrainType()
            m13tPlot = CyMap().plot((Rollx - 1),(Rolly + 1)).getTerrainType()
            m20tPlot = CyMap().plot(Rollx,(Rolly - 2)).getTerrainType()
            m23tPlot = CyMap().plot(Rollx,(Rolly + 1)).getTerrainType()
           
            m11tPlot = m11Plot.getTerrainType()
            m12tPlot = m12Plot.getTerrainType()
            m21tPlot = m21Plot.getTerrainType()
            m22tPlot = m22Plot.getTerrainType()
            
            if (m13tPlot != CraterRim) and (m23tPlot != CraterRim) and (m10tPlot != CraterRim) and (m20tPlot != CraterRim) and (m31tPlot != CraterRim) and (m32tPlot != CraterRim) and (m01tPlot != CraterRim) and (m02tPlot != CraterRim) and (m11tPlot != CraterRim) and (m12tPlot != CraterRim) and (m21tPlot != CraterRim) and (m22tPlot != CraterRim) and (not m11Plot.isPeak()) and (not m12Plot.isPeak()) and (not m21Plot.isPeak()) and (not m22Plot.isPeak()):
                m11Plot.setTerrainType(gc.getInfoTypeForString("TERRAIN_CRATERRIM"), 0, 0)
                m21Plot.setTerrainType(gc.getInfoTypeForString("TERRAIN_CRATERRIM"), 0, 0)
                m12Plot.setTerrainType(gc.getInfoTypeForString("TERRAIN_CRATERRIM"), 0, 0)
                m22Plot.setTerrainType(gc.getInfoTypeForString("TERRAIN_CRATERRIM"), 0, 0)
   #     return None

def add_He3():
#add He3 resources near player
    gc = CyGlobalContext()
    CraterRim = gc.getInfoTypeForString("TERRAIN_CRATERRIM")
    DustSea = gc.getInfoTypeForString("TERRAIN_DUSTSEA")
    He3 = gc.getInfoTypeForString("BONUS_HELIUM3")
    for iI in range(gc.getMAX_CIV_PLAYERS()):
	if (gc.getPlayer(iI).isAlive()):
            iStartX = gc.getPlayer(iI).getStartingPlot().getX()
            iStartY = gc.getPlayer(iI).getStartingPlot().getY()
            dice = gc.getGame().getMapRand()
            NumOfHe3 = 1 + dice.get(1, "number of Helium 3")
            x = 0
            loop = 0
            while (x < 1) and (loop < 100):
                loop = loop + 1
                xloc = iStartX + dice.get(5, "x location") - 2
                yloc = iStartY + dice.get(5, "y location") - 2
                mPlot = CyMap().plot(xloc,yloc)
                mtPlot = mPlot.getTerrainType()
                if (mtPlot != CraterRim) and (mtPlot != DustSea) and (not mPlot.isPeak()):
                    mPlot.setBonusType(He3)
                    x = x + 1
            while (x < NumOfHe3) and (loop < 100):
                loop = loop + 1
                xloc = iStartX + dice.get(7, "x location") - 3
                yloc = iStartY + dice.get(7, "y location") - 3
                mPlot = CyMap().plot(xloc,yloc)
                mtPlot = mPlot.getTerrainType()
                if (mtPlot != CraterRim) and (mtPlot != DustSea) and (not mPlot.isPeak()):
                    mPlot.setBonusType(He3)
                    x = x + 1





















"""
def assignStartingPlots():
	# In order to prevent "pockets" from forming, where civs can be blocked in 
	# by Peaks or lakes, causing a "dud" map, pathing must be checked for each 
	# new start plot before it hits the map. Any pockets that are detected must 
	# be opened. The following process takes care of this need. Soren created a 
	# useful function that already lets you know how far a given plot is from
	# the closest nearest civ already on the board. MinOriginalStartDist is that 
	# function. You can get-- or setMinoriginalStartDist() as a value attached 
	# to each plot. Any value of -1 means no valid land-hills-only path exists to
	# a civ already placed. For Highlands, that means we have found a pocket 
	# and it must be opened. A valid legal path from all civs to all other civs 
	# is required for this map to deliver reliable, fun games every time.
	#
	# - Sirian
	#
	gc = CyGlobalContext()
	map = CyMap()
	dice = gc.getGame().getMapRand()
	iW = map.getGridWidth()
	iH = map.getGridHeight()
	iPlayers = gc.getGame().countCivPlayersEverAlive()
	iNumStartsAllocated = 0
	start_plots = []
	print "==="
	print "Number of players:", iPlayers
	print "==="

	terrainPlains = gc.getInfoTypeForString("TERRAIN_MARIABASALT")

	# Obtain player numbers. (Account for possibility of Open slots!)
	player_list = []
	for plrCheckLoop in range(18):
		if CyGlobalContext().getPlayer(plrCheckLoop).isEverAlive():
			player_list.append(plrCheckLoop)
	# Shuffle players so that who goes first (and gets the best start location) is randomized.
	shuffledPlayers = []
	for playerLoopTwo in range(gc.getGame().countCivPlayersEverAlive()):
		iChoosePlayer = dice.get(len(player_list), "Shuffling Players - Highlands PYTHON")
		shuffledPlayers.append(player_list[iChoosePlayer])
		del player_list[iChoosePlayer]

	# Loop through players, assigning starts for each.
	for assign_loop in range(iPlayers):
		playerID = shuffledPlayers[assign_loop]
		player = gc.getPlayer(playerID)
		
		# Use the absolute approach for findStart from CvMapGeneratorUtil, which 
		# ignores areaID quality and finds the best local situation on the board.
		findstart = CvMapGeneratorUtil.findStartingPlot(playerID)
		sPlot = map.plotByIndex(findstart)
		
		# Record the plot number to the data array for use if needed to open a "pocket".
		iStartX = sPlot.getX()
		iStartY = sPlot.getY()
		
		# If first player placed, no need to check for pathing yet.
		if assign_loop == 0:
			start_plots.append([iStartX, iStartY])
			player.setStartingPlot(sPlot, true) # True flag causes data to be refreshed for MinOriginalStartDist data cells in plots on the same land mass.
                        add_He3(iStartX,iStartY)
			print "-+-+-"
			print "Player"
			print playerID
			print "First player assigned."
			print "-+-+-"
			continue
		
		# Check the pathing in the start plot.
		if sPlot.getMinOriginalStartDist() != -1:
			start_plots.append([iStartX, iStartY])
			player.setStartingPlot(sPlot, true)
			add_He3(iStartX,iStartY)
			print "-+-+-"
			print "Player"
			print playerID
			print "Open Path, no problems."
			print "-+-+-"
			continue
		
		# If the process has reached this point, then this player is stuck 
		# in a "pocket". This could be an island, a valley surrounded by peaks, 
		# or an area blocked off by peaks. Could even be that a major line 
		# of peaks and lakes combined is bisecting the entire map.
		print "-----"
		print "Player"
		print playerID
		print "Pocket detected, attempting to resolve..."
		print "-----"
		#
		# First step is to identify which existing start plot is closest.
		print "Pocket Plot"
		print iStartX, iStartY
		print "---"
		[iEndX, iEndY] = start_plots[0]
		fMinDistance = sqrt(((iStartX - iEndX) ** 2) + ((iStartY - iEndY) ** 2))
		for check_loop in range(1, len(start_plots)):
			[iX, iY] = start_plots[check_loop]
			if fMinDistance > sqrt(((iStartX - iX) ** 2) + ((iStartY - iY) ** 2)):
				# Closer start plot found!
				[iEndX, iEndY] = start_plots[check_loop]
				fMinDistance = sqrt(((iStartX - iX) ** 2) + ((iStartY - iY) ** 2))
		print "Nearest player (path destination)"
		print iEndX, iEndY
		print "---"
		print "Absolute distance:"
		print fMinDistance
		print "-----"
		
		# Now we draw an invisible line, plot by plot, one plot wide, from 
		# the current start to the nearest start, converting peaks along the 
		# way in to hills, and lakes in to flatlands, until a path opens.
		
		# Bulldoze the path until it opens!
		startPlot = map.plot(iStartX, iStartY)
		endPlot = map.plot(iEndX, iEndY)
		if abs(iEndY-iStartY) < abs(iEndX-iStartX):
			# line is closer to horizontal
			if iStartX > iEndX:
				startX, startY, endX, endY = iEndX, iEndY, iStartX, iStartY # swap start and end
				bReverseFlag = True
				print "Path reversed, working from the end plot."
			else: # don't swap
				startX, startY, endX, endY = iStartX, iStartY, iEndX, iEndY
				bReverseFlag = False
				print "Path not reversed."
			dx = endX-startX
			dy = endY-startY
			if dx == 0 or dy == 0:
				slope = 0
			else:
				slope = float(dy)/float(dx)
			print("Slope: ", slope)
			y = startY
			for x in range(startX, endX):
				print "Checking plot"
				print x, int(round(y))
				print "---"
				if map.isPlot(x, int(round(y))):
					i = map.plotNum(x, int(round(y)))
					pPlot = map.plotByIndex(i)
					y += slope
					print("y plus slope: ", y)
					if pPlot.isHills() or pPlot.isFlatlands(): continue # on to next plot!
					if pPlot.isPeak():
						print "Peak found! Bulldozing this plot."
						print "---"
						pPlot.setPlotType(PlotTypes.PLOT_LAND, true, true)
						if bReverseFlag:
							currentDistance = map.calculatePathDistance(pPlot, startPlot)
						else:
							currentDistance = map.calculatePathDistance(pPlot, endPlot)
						if currentDistance != -1: # The path has been opened!
							print "Pocket successfully opened!"
							print "-----"
							break
					elif pPlot.isWater():
						print "Lake found! Filling in this plot."
						print "---"
						pPlot.setPlotType(PlotTypes.PLOT_LAND, true, true)
						pPlot.setTerrainType(terrainPlains, true, true)
						if pPlot.getBonusType(-1) != -1:
							print "########################"
							print "A sea-based Bonus is now present on the land! EEK!"
							print "########################"
							pPlot.setBonusType(-1)
							print "OK, nevermind. The resource has been removed."
							print "########################"
						if bReverseFlag:
							currentDistance = map.calculatePathDistance(pPlot, startPlot)
						else:
							currentDistance = map.calculatePathDistance(pPlot, endPlot)
						if currentDistance != -1: # The path has been opened!
							print "Pocket successfully opened!"
							print "-----"
							break

		else:
			# line is closer to vertical
			if iStartY > iEndY:
				startX, startY, endX, endY = iEndX, iEndY, iStartX, iStartY # swap start and end
				bReverseFlag = True
				print "Path reversed, working from the end plot."
			else: # don't swap
				startX, startY, endX, endY = iStartX, iStartY, iEndX, iEndY
				bReverseFlag = False
				print "Path not reversed."
			dx, dy = endX-startX, endY-startY
			if dx == 0 or dy == 0:
				slope = 0
			else:
				slope = float(dx)/float(dy)
			print("Slope: ", slope)
			x = startX
			for y in range(startY, endY+1):
				print "Checking plot"
				print int(round(x)), y
				print "---"
				if map.isPlot(int(round(x)), y):
					i = map.plotNum(int(round(x)), y)
					pPlot = map.plotByIndex(i)
					x += slope
					print("x plus slope: ", x)
					if pPlot.isHills() or pPlot.isFlatlands(): continue # on to next plot!
					if pPlot.isPeak():
						print "Peak found! Bulldozing this plot."
						print "---"
						pPlot.setPlotType(PlotTypes.PLOT_LAND, true, true)
						if bReverseFlag:
							currentDistance = map.calculatePathDistance(pPlot, startPlot)
						else:
							currentDistance = map.calculatePathDistance(pPlot, endPlot)
						if currentDistance != -1: # The path has been opened!
							print "Pocket successfully opened!"
							print "-----"
							break
					elif pPlot.isWater():
						print "Lake found! Filling in this plot."
						print "---"
						pPlot.setPlotType(PlotTypes.PLOT_LAND, true, true)
						pPlot.setTerrainType(terrainPlains, true, true)
						if pPlot.getBonusType(-1) != -1:
							print "########################"
							print "A sea-based Bonus is now present on the land! EEK!"
							print "########################"
							pPlot.setBonusType(-1)
							print "OK, nevermind. The resource has been removed."
							print "########################"
						if bReverseFlag:
							currentDistance = map.calculatePathDistance(pPlot, startPlot)
						else:
							currentDistance = map.calculatePathDistance(pPlot, endPlot)
						if currentDistance != -1: # The path has been opened!
							print "Pocket successfully opened!"
							print "-----"
							break
			
		# Now that all the pathing for this player is resolved, set the start plot.
		start_plots.append([iStartX, iStartY])
		player.setStartingPlot(sPlot, true)

                add_He3(iStartX,iStartY)
    
                
	# All done!
	print "**********"
	print "All start plots assigned!"
	print "**********"


   

	
	return None
"""


def normalizeAddRiver():
	return None

def normalizeRemovePeaks():
	return None

def normalizeAddLakes():
	return None

def normalizeRemoveBadFeatures():
	return None

def normalizeRemoveBadTerrain():
	return None

def normalizeAddFoodBonuses():
    	return None

def normalizeAddGoodTerrain():
	return None

def normalizeAddExtras():
	return None

def startHumansOnSameTile():
        gc = CyGlobalContext()
	map = CyMap()
	iW = map.getGridWidth()
	iH = map.getGridHeight()
        for x in range(iW):
                    for y in range(iH):
                        mPlot = CyMap().plot(x,y)
                        if (mPlot.getTerrainType() == gc.getInfoTypeForString("TERRAIN_OCEAN")) or (mPlot.getTerrainType() == gc.getInfoTypeForString("TERRAIN_DUSTSEA_WATER")):
                            mPlot.setTerrainType(gc.getInfoTypeForString("TERRAIN_DUSTSEA"), 0, 0)
          
        add_He3()


	"Returns true if all human units should start on the same tile"
	return True
